package main

import (
    "fmt"
    "os"
    "os/exec"
    "runtime"
)

func main() {
    osType := runtime.GOOS

    // 假设程序路径为 /usr/local/myapp/my-startup-program
    programDir := "/usr/local/myapp"
    programPath := programDir + "/my-startup-program"

    // 如果目录不存在，创建目录
    if _, err := os.Stat(programDir); os.IsNotExist(err) {
        err := os.Mkdir(programDir, 0755)
        if err != nil {
            fmt.Println("创建程序目录时出错:", err)
            return
        }
    }

    switch osType {
    case "linux":
        fmt.Println("当前系统为 Linux，正在检测是否支持 systemd...")
        if checkIfSystemdExists() {
            fmt.Println("检测到 systemd，正在创建 systemd 服务...")
            createLinuxService(programPath, programDir)
        } else {
            fmt.Println("未检测到 systemd，正在创建 SysVinit 启动脚本...")
            createSysVinitScript(programPath, programDir)
        }
    case "freebsd":
        fmt.Println("当前系统为 FreeBSD，正在创建 rc.d 脚本...")
        createFreeBSDScript(programPath, programDir)
    default:
        fmt.Println("不支持的操作系统:", osType)
    }
}

// 检查是否支持 systemd
func checkIfSystemdExists() bool {
    cmd := exec.Command("pidof", "systemd")
    err := cmd.Run()
    return err == nil
}

// 创建 Linux 的 systemd 服务文件
func createLinuxService(programPath, workingDir string) {
    serviceContent := fmt.Sprintf(`[Unit]
Description=Go 开机启动程序
After=network.target

[Service]
WorkingDirectory=%s
ExecStart=%s
Restart=always
User=%s
Environment=MYAPP_CONFIG=config.yaml

[Install]
WantedBy=multi-user.target
`, workingDir, programPath, os.Getenv("USER"))

    servicePath := "/etc/systemd/system/my-startup-program.service"

    // 写入 systemd 服务文件
    err := os.WriteFile(servicePath, []byte(serviceContent), 0644)
    if err != nil {
        fmt.Println("创建 systemd 服务文件时出错:", err)
        return
    }

    // 设置服务开机自启
    enableAndStartService("systemctl", "enable", "my-startup-program")
    enableAndStartService("systemctl", "start", "my-startup-program")
    fmt.Println("Linux systemd 服务文件创建并成功启用。")
}

// 创建 Linux 的 SysVinit 启动脚本
func createSysVinitScript(programPath, workingDir string) {
    scriptContent := fmt.Sprintf(`#!/bin/sh
### BEGIN INIT INFO
# Provides:          my_startup_program
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Go 开机启动程序
### END INIT INFO

case "$1" in
    start)
        echo "Starting my_startup_program..."
        cd %s
        %s &
        ;;
    stop)
        echo "Stopping my_startup_program..."
        killall my-startup-program
        ;;
    restart)
        echo "Restarting my_startup_program..."
        $0 stop
        $0 start
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
        ;;
esac

exit 0
`, workingDir, programPath)

    scriptPath := "/etc/init.d/my_startup_program"

    // 写入 SysVinit 启动脚本
    err := os.WriteFile(scriptPath, []byte(scriptContent), 0755)
    if err != nil {
        fmt.Println("创建 SysVinit 启动脚本时出错:", err)
        return
    }

    // 启用 SysVinit 服务
    enableAndStartService("update-rc.d", "my_startup_program", "defaults")
    enableAndStartService("service", "my_startup_program", "start")
    fmt.Println("SysVinit 启动脚本创建并成功启用。")
}

// 创建 FreeBSD 的 rc.d 脚本
func createFreeBSDScript(programPath, workingDir string) {
    scriptContent := fmt.Sprintf(`#!/bin/sh
#
# PROVIDE: my_startup_program
# REQUIRE: NETWORKING
# KEYWORD: shutdown

. /etc/rc.subr

name="my_startup_program"
rcvar=my_startup_program_enable

command="%s"
command_args="&"
pidfile="/var/run/my-startup-program.pid"
workdir="%s"

load_rc_config $name
: ${my_startup_program_enable:=no}

# 如果工作目录不存在，返回错误
if [ ! -d "$workdir" ]; then
    echo "工作目录 $workdir 不存在，启动失败"
    exit 1
fi

# 设置工作目录
cd $workdir

run_rc_command "$1"
`, programPath, workingDir)

    scriptPath := "/usr/local/etc/rc.d/my_startup_program"

    // 写入 rc.d 启动脚本
    err := os.WriteFile(scriptPath, []byte(scriptContent), 0755)
    if err != nil {
        fmt.Println("创建 rc.d 脚本时出错:", err)
        return
    }

    // 启用 rc.d 服务
    enableAndStartService("sysrc", "my_startup_program_enable=YES")
    enableAndStartService("service", "my_startup_program", "start")
    fmt.Println("FreeBSD rc.d 脚本创建并成功启用。")
}

// 启用并启动服务的通用函数
func enableAndStartService(command string, args ...string) {
    cmd := exec.Command(command, args...)
    output, err := cmd.CombinedOutput()
    if err != nil {
        fmt.Printf("执行命令 %s 时出错: %s\n", command, err)
    }
    fmt.Println(string(output))
}
